<template>
  <div class="float-ball" :style="{
    left: position.x + 'px',
    top: position.y + 'px',
    width: props.width + 'px',
    height: props.height + 'px'
  }" @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd">
    <slot>
      <img :src="iconSignup" :style="{
        width: props.width + 'px',
        height: props.height + 'px'
      }">
    </slot>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import iconSignup from '/images/competition/icon-signup.png'

const props = defineProps({
  width: { type: Number, default: 50 },
  height: { type: Number, default: 50 }
})

const position = ref({ x: 300, y: 500 })
const startOffset = ref({ x: 0, y: 0 })
const currentSide = ref('none') // 'left', 'right', 'none'

const screenWidth = ref(window.innerWidth)
const screenHeight = ref(window.innerHeight)

function updateScreenSize () {
  screenWidth.value = window.innerWidth
  screenHeight.value = window.innerHeight
}

function autoStickToEdge () {
  const middle = screenWidth.value / 2
  if (position.value.x < middle) {
    position.value.x = 10
    currentSide.value = 'left'
  } else {
    position.value.x = screenWidth.value - props.width - 10
    currentSide.value = 'right'
  }

  position.value.y = Math.min(Math.max(0, position.value.y), screenHeight.value - props.height)
}

function onResize () {
  updateScreenSize()

  if (currentSide.value === 'left') {
    position.value.x = 10
  } else if (currentSide.value === 'right') {
    position.value.x = screenWidth.value - props.width - 10
  }
  position.value.y = Math.min(position.value.y, screenHeight.value - props.height)
}

onMounted(() => {
  updateScreenSize()
  autoStickToEdge()
  window.addEventListener('resize', onResize)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', onResize)
})

const onTouchStart = (e) => {
  const touch = e.touches[0]
  startOffset.value.x = touch.clientX - position.value.x
  startOffset.value.y = touch.clientY - position.value.y
}

const onTouchMove = (e) => {
  e.preventDefault()
  const touch = e.touches[0]
  let x = touch.clientX - startOffset.value.x
  let y = touch.clientY - startOffset.value.y

  x = Math.min(Math.max(0, x), screenWidth.value - props.width)
  y = Math.min(Math.max(0, y), screenHeight.value - props.height)

  position.value = { x, y }
  currentSide.value = 'none'
}

const onTouchEnd = () => {
  autoStickToEdge()
}
</script>

<style scoped>
.float-ball {
  position: fixed;
  background-color: #1989fa;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  user-select: none;
  touch-action: none;
  z-index: 999;
  overflow: hidden;

  .float-ball-icon {
    width: 100%;
    height: 100%;
  }
}
</style>
